home *** CD-ROM | disk | FTP | other *** search
- .model large
- .8086
- ;.stack 100h
-
- ax25_code segment word public
- assume cs:ax25_code, ds:ax25_code
-
- org 2ch
- phd_environ dw ?
-
- szczyt_kolejki EQU 216Eh
- org 100h
- start: jmp install_driver
-
- txt1: db 'TFPCX-2-TCP/IP Version 0.4b',13,10
- db 'Packet driver that allows using TFPCX with NOS software',13,10
- db '(C) 1995 by Piotrek Kaczmarzyk, SQ6BOT',13,10,10
- db 'This little piece of code is a CARDWARE - please read DOC file',13,10
- db 'Free license granted to radio amateurs only.',13,10,10,'$'
- txt2: db 'TFPCX V2.0 detected.',13,10,'$'
- txt3: db 'Error: This program works only with TFPCX V2.0.',13,10,'$'
- txt4: db 'Error: TFPCX not loaded.',13,10,'$'
- host: db 'Switching TFPCX to Host Mode.',13,10,'$'
- JHOST: db 27,'JHOST1',13
- JHOSTend:
- count dw 0
- packet_int_no db 60h ; default packet interrupt number
- bak_es dw 0
- bak_si dw 0
- bak_cx dw 0
- bufadr dw 0
- bufseg dw 0
- bufofs dw 0
- data_s dw 0
- s_len dw 0 ; dlugosc ramki
- s_frm dw 0 ; adres obecnie analizowanej ramki
- s_pos dw 0 ; pozycja w ramce
- s_pos_org dw 0
- s_prev dw 0 ; poprzednia ramka
- s_cnt dw 0
-
- HostMode:
- mov bx,offset JHOST
- nxt: mov ah,3
- mov al,[bx]
- int 0FDh
- inc bx
- cmp bx,offset JHOSTend
- jne nxt
- ret
-
- ;==========================================================================
- proc_5E60:
- lea ax,[bx+28h]
- mov [bx+08h],ax
- mov word ptr [bx+0Ch],0000h
- ret
-
- proc_5E6C:
- push bp
- mov bp,sp
- sub sp,0004h
- pushf
- cli
- mov ax,ds:[14E8h]
- dec word ptr ds:[14E8h]
- or ax,ax
- jnz loc_5E82
- stc
- jmp return
- ; < ERROR - NO MORE FREE BUFFERS
- loc_5E82:
- mov bx,ds:[12F2h]
- call proc_5E94
- mov [bp-02h],ax
- popf
- mov ax,[bp-02h]
- clc
- return:
- mov sp,bp
- pop bp
- ret
-
- create_frame:
- push ax
- push bx
- push cx
- push si
- mov bx,ax
- add_next_char:
- cmp cx,0000h
- je w_buforze
- mov al,es:[si]
- push bx
- call proc_5E0A ; al = char, bx = buffer address
- pop bx
- dec cx
- inc si
- jmp add_next_char
- w_buforze:
- pop si
- pop cx
- pop bx
- pop ax
- ret
-
- proc_5E0A:
- push bp
- mov bp,sp
- push ax
- push si
- mov si,bx
- mov ax,[si+0Ah]
- inc word ptr [si+0Ah]
- test al,1Fh
- jnz loc_5E2C
- call proc_5E6C
- mov bx,ax
- mov ax,[si+06h]
- call proc_5EB6
- add ax,0004h
- mov [si+08h],ax
- loc_5E2C:
- mov al,[bp-02h]
- mov bx,[si+08h]
- mov [bx],al
- inc word ptr [si+08h]
- pop si
- mov sp,bp
- pop bp
- ret
-
- sendpkt:
- call rst_ds
- call proc_5E6C ; allocate
- call create_frame
- mov bx,ax
- call proc_5E60 ; refresh
- mov ax,ds:[2034]
- mov [si+0Eh],ax
- mov byte ptr [bx+10h],02h
- mov byte ptr [bx+11h],00h
- mov byte ptr [bx+12h],00h ; nr_modemu = [14E6]
- call proc_5834 ; send_it
- clc
- mov dh,NO_ERROR
- ret
-
- rst_ds:
- push cs
- pop ds
- push ax
- mov ax,data_s
- mov ds,ax
- pop ax
- ret
-
- no_more_buffers:
- jmp pkterror
-
- proc_5834:
- push bp
- mov bp,sp
- sub sp,0002h
- push bx
- push si
- mov al,[bx+12h]
- sub ah,ah
- mov [bp-02h],ax
- mov si,ax
- shl si,1
- inc word ptr [si+1470h]
- cmp word ptr ds:[14E8h],0040h
- jbe out_of_buffers
- call proc_5E60
- pushf
- cli
- mov bx,[bp-02]
- shl bx,1
- shl bx,1
- mov ax,[bx+1532h]
- mov bx,[bp-04]
- call proc_5EB6
- mov bx,[bp-02]
- cmp byte ptr [bx+78DEh],00h
- jnz problems
- mov ax,bx
- call final_send
- jmp koncowka
- problems:
- mov byte ptr [bx+1FFCh],01h
- koncowka:
- popf
- pop si
- mov sp,bp
- pop bp
- ret
-
- out_of_buffers:
- mov bx,[bp-04h]
- mov ax,ds:[2170h]
- call proc_5EB6
- pop si
- mov sp,bp
- pop bp
- ret
-
- final_send:
- push bp
- mov bp,sp
- sub sp,0002h
- push ax
- cmp al,ds:[201Eh]
- jb loc1
- jmp something
- loc1:
- mov bl,al
- sub bh,bh
- cmp [bx+20E6h],bh
- jnz loc2
- jmp something
- loc2:
- shl bx,1
- cmp byte ptr [bx+798Eh],00h
- jz loc3
- mov al,30h
- mul byte ptr [bx+798Fh]
- mov bx,ax
- mov word ptr [bx+78ACh],0001h
- mov sp,bp
- pop bp
- ret
- loc3:
- mov bl,[bp-04h]
- sub bh,bh
- shl bx,1
- mov al,1Ch
- mul byte ptr [bx+798Fh]
- mov bx,ax
- add bx,20FEh
- mov [bp-02h],bx
- cmp byte ptr [bx+0Ah],00h
- jz something
- pushf
- cli
- mov bx,[bp-02h]
- mov al,[bx+14h]
- sub ah,ah
- jmp loc4
- loc10:
- mov bl,[bp-04h]
- sub bh,bh
- cmp [bx+1518h],bh
- jz loc9
- loc6:
- mov ax,0001h
- loc5:
- mov bx,[bp-02h]
- mov [bx+16h],ax
- mov bx,[bp-02h]
- mov byte ptr [bx+14h],01h
- jmp loc7
- loc9:
- mov bl,[bp-04h]
- sub bh,bh
- cmp [bx+20D6h],bh
- jz loc6
- mov al,[bx+20D6h]
- sub ah,ah
- jmp loc5
- loc8:
- mov bx,[bp-02h]
- mov word ptr [bx+16h],0001h
- mov byte ptr [bx+14h],02h
- jmp loc7
- loc4:
- or ax,ax
- jz loc10
- sub ax,0005h
- jz loc8
- loc7:
- popf
- mov sp,bp
- pop bp
- ret
-
- something:
- mov ah,[bp-04h]
- sub al,al
- or ax,8001h
- call proc_5D62
- mov sp,bp
- pop bp
- ret
-
- proc_5D62:
- push di
- push si
- mov dx,ax
- mov cl,08h
- mov si,ax
- and si,7F00h
- shr si,cl
- mov ax,si
- shl si,1
- add si,1520h
- mov di,ax
- shl di,1
- shl di,1
- add di,1530h
- cmp word ptr [si],0000h
- je loc_a
- mov bx,[si]
- mov ax,ds:[2170h]
- call proc_5EB6
- mov word ptr [si],0000h
- loc_a: mov bx,di
- call proc_5DF0
- pop si
- pop di
- ret
-
- proc_5DF0:
- push si
- cmp [bx],bx
- je loc_b
- mov si,bx
- loc_c: mov bx,[si]
- call proc_5E94
- mov bx,ax
- mov ax,ds:[2170h]
- call proc_5EB6
- cmp [si],si
- jne loc_c
- loc_b: pop si
- ret
-
- proc_5E94:
- push bp
- mov bp,sp
- push bx
- push si
- pushf
- cli
- mov bx,[bp-02h]
- mov ax,[bx]
- mov si,[bx+2]
- mov [si],ax
- mov ax,[bx+02h]
- mov bx,[bx]
- mov [bx+02h],ax
- popf
- mov ax,[bp-02h]
- pop si
- mov sp,bp
- pop bp
- ret
-
- proc_5EB6:
- push bp
- mov bp,sp
- push ax
- push bx
- push di
- push si
- pushf
- cli
- mov bx,[bp-02h]
- mov ax,[bx]
- mov si,[bp-04h]
- mov [si],ax
- mov [si+02h],bx
- mov di,[si]
- mov [di+02h],si
- mov [bx],si
- popf
- mov ax,[bp-04h]
- pop si
- pop di
- mov sp,bp
- pop bp
- ret
-
- ;=====================================================
- ; RECEIVING PART
- ;=====================================================
-
-
- doupcallnow:
- pushf
- push bp
- push bx
- push ax
- push cx
- push dx
- push di
- push si
- push ds
- push es
- mov bx,szczyt_kolejki
- next_frame:
- call rst_ds
- mov bx,[bx]
- mov cx,bx
- cmp bx,szczyt_kolejki
- jne short is_packet
- jmp no_packet
- is_packet:
- call rst_ds
- call proc_5E60 ; refresh
- push cs
- pop ds
- mov count,0
- copy_next_byte:
- call rst_ds
- mov ax,[bx+0Ch]
- cmp ax,[bx+0Ah]
- je copy_end
- call proc_5E3C
- push bx
- push cs
- pop ds
- mov bx,offset buf
- add bx,count
- cmp bx,offset over_buf
- jae no_packet2
- mov ds:[bx],al
- inc count
- pop bx
- jmp copy_next_byte
-
- no_packet2:
- pop bx
- jmp no_packet
-
- copy_end:
- push cs
- pop ds
- push bx
- call DoUpCall
- pop bx
-
- ; mov [bx+28h],0A8A8h
- jmp next_frame
-
- no_packet:
- pop es
- pop ds
- pop si
- pop di
- pop dx
- pop cx
- pop ax
- pop bx
- pop bp
- popf
-
- mov [bp-08h],ax
- cmp ax,szczyt_kolejki
- db 0EAh,0B1h,46h
- jump2: dw 0
-
-
- proc_5E3C:
- push si
- mov ax,[bx+0Ch]
- inc word ptr [bx+0Ch]
- test al,1Fh
- jnz loc_z
- mov si,[bx+08h]
- mov ax,[si-24h]
- add ax,0004h
- mov [bx+08h],ax
- loc_z:
- mov si,[bx+08h]
- inc word ptr [bx+08h]
- mov al,[si]
- sub ah,ah
- pop si
- ret
-
- drvr_class db 9 ;driver's class - default is 9 that is AX.25
- driver_name db 'Packet driver overlay for TFPCX',0
-
- even
- old_packet_int dw 0,0 ;saves software interrupt vector
- receive_upcall dw 0,0 ;keeps application "upcall" routine address
-
- ;==============================================================
- ;Service routine for software interrupt to control the driver
-
- ; Packet Driver Error numbers
- NO_ERROR equ 0 ;no error at all.
- BAD_HANDLE equ 1 ;invalid handle number
- NO_CLASS equ 2 ;no interfaces of specified class found
- NO_TYPE equ 3 ;no interfaces of specified type found
- NO_NUMBER equ 4 ;no interfaces of specified number found
- BAD_TYPE equ 5 ;bad packet type specified
- NO_MULTICAST equ 6 ;this interface does not support multicast
- CANT_TERMINATE equ 7 ;this packet driver cannot terminate
- BAD_MODE equ 8 ;an invalid receiver mode was specified
- NO_SPACE equ 9 ;operation failed because of insufficient space
- TYPE_INUSE equ 10 ;the type had previously been accessed, and not released.
- BAD_COMMAND equ 11 ;the command was out of range, or not implemented
- CANT_SEND equ 12 ;the packet couldn't be sent (usually hardware error)
- CANT_SET equ 13 ;hardware address couldn't be changed (more than 1 handle open)
- BAD_ADDRESS equ 14 ;hardware address has bad length or format
- CANT_RESET equ 15 ;Couldn't reset interface (more than 1 handle open).
- BAD_IOCB equ 16 ;an invalid iocb was specified
-
- regs_w struc ; stack offsets of incoming regs
- _ES dw ?
- _DS dw ?
- _bp dw ?
- _DI dw ?
- _SI dw ?
- _DX dw ?
- _CX dw ?
- _BX dw ?
- _AX dw ?
- _IP dw ?
- _CS dw ?
- _F dw ? ; flags, Carry flag is bit 0
- regs_w ends
-
- CY equ 0001h
- EI equ 0200h
-
- regs_b struc ; stack offsets of incoming regs
- dw ? ; es, ds, bp, di, si are 16 bits
- dw ?
- dw ?
- dw ?
- dw ?
- _DL db ?
- _DH db ?
- _CL db ?
- _CH db ?
- _bl db ?
- _bh db ?
- _AL db ?
- _AH db ?
- regs_b ends
-
- DRVR_ISR: ;service interrupt vector points here
- ;application layer calls enter this point
- ;via a software interrupt
- jmp exec_command ;entry point must be a jump
- db 'PKT DRVR',0 ;followed by this string
-
- exec_command: ;packet driver command executor
- sti ;don't lock interrupts
- push ax ;save registers on stack
- push bx
- push cx
- push dx
- push si
- push di
- push bp
- push ds
- push es
- mov bp,sp ;bp=sp so we can address pushed registers
- and _F[bp],not CY ;Clear carry on exit
- mov bx,cs ;make ds=cs
- mov ds,bx
- mov bl,ah ;execute command given by ah
- mov bh,0
- cmp bx,26
- jnc f_above_25
- add bx,bx
- call [functions+bx]
- DRVR_ISR_return:
- mov _DH[bp],dh ;pass dh-now to dh-on-exit
- sbb ax,ax
- and ax,CY
- or _F[bp],ax ;pass carry-now to carry-on-exit
- pop es
- pop ds
- pop bp
- pop di
- pop si
- pop dx
- pop cx
- pop bx
- pop ax
- iret
-
- f_above_25:
- call f_not_implemented
- jmp short DRVR_ISR_return
-
- even
- functions label word
- dw f_not_implemented ;0
- dw f_driver_info ;1
- dw f_access_type ;2
- dw f_release_type ;3
- dw f_send_pkt ;4
- dw f_terminate ;5
- dw f_get_address ;6
- dw f_reset_interface ;7
- dw f_stop ;8
- dw f_not_implemented ;9
- dw f_get_parameters ;10
- dw f_not_implemented ;11
- dw f_as_send_pkt ;12
- dw f_drop_pkt ;13
- dw f_not_implemented ;14
- dw f_not_implemented ;15
- dw f_not_implemented ;16
- dw f_not_implemented ;17
- dw f_not_implemented ;18
- dw f_not_implemented ;19
- dw f_set_rcv_mode ;20
- dw f_get_rcv_mode ;21
- dw f_set_multicast_list ;22
- dw f_get_multicast_list ;23
- dw f_get_statistics ;24
- dw f_set_address ;25
-
- f_driver_info:
- mov dh,drvr_class ;driver class
- mov _CH[bp],dh
- mov _AL[bp],1 ;basic flag
- mov _DX[bp],0 ;driver type
- mov _CL[bp],0 ;driver number
- mov _BX[bp],0 ;driver version
- mov _DS[bp],ds ;driver name pointer
- mov _SI[bp],offset driver_name
- mov dh,NO_ERROR
- clc
- ret
-
- f_access_type:
- mov bx,_BX[bp]
- cmp al,drvr_class ;our class ?
- jnz wrong_class
- cmp bx,0FFFFh ;generic type ?
- jz type_OK
- cmp bx,0 ;our type ?
- jnz wrong_type
- type_OK:
- cmp dl,0 ;generic num ?
- jnz wrong_num
- mov ax,receive_upcall ;check if handle busy
- or ax,receive_upcall+2
- jnz busy_handle
- mov receive_upcall,di ;store receiver upcall
- mov ax,es
- mov receive_upcall+2,ax
- mov _AX[bp],0 ;return handle=0
- clc
- mov dh,NO_ERROR
- ret
-
- wrong_class:
- stc
- mov dh,NO_CLASS
- ret
- wrong_type:
- stc
- mov dh,NO_TYPE
- ret
- wrong_num:
- stc
- mov dh,NO_NUMBER
- ret
- busy_handle:
- stc
- mov dh,TYPE_INUSE
- ret
- pkterror:
- stc
- mov dh,CANT_SEND
- ret
-
- f_stop: jmp short clear_upcall
-
- f_release_type:
- cmp _BX[bp],0 ;handle=0 ?
- jnz wrong_handle
- mov ax,receive_upcall ;is receiver upcall defined?
- or ax,receive_upcall+2
- jz wrong_handle ;jump if not
- clear_upcall:
- xor ax,ax ;receiver upcall := 0:0
- mov receive_upcall,ax ;this means "upcall address is not valid"
- mov receive_upcall+2,ax
- clc
- mov dh,NO_ERROR
- ret
-
- wrong_handle:
- stc
- mov dh,BAD_HANDLE
- ret
-
- f_send_pkt:
- mov es,_DS[bp] ;es:si=packet address, cx=packet length
- jmp sendpkt
-
- f_terminate:
- clc
- mov dh,NO_ERROR
- ret
-
- f_get_address:
- xor cx,cx ;return zero-length address
- clc
- mov dh,NO_ERROR
- ret
-
- f_reset_interface: jmp short f_not_implemented
- f_get_parameters: jmp short f_not_implemented
- f_as_send_pkt: jmp short f_not_implemented
- f_drop_pkt: jmp short f_not_implemented
- f_set_rcv_mode: jmp short f_not_implemented
- f_get_rcv_mode: jmp short f_not_implemented
- f_set_multicast_list: jmp short f_not_implemented
- f_get_multicast_list: jmp short f_not_implemented
-
- f_get_statistics: jmp short f_not_implemented
-
- f_set_address: jmp short f_not_implemented
-
- f_not_implemented: ;non-implemented functions jump here
- stc ;set carry to indicate an error
- mov dh,BAD_COMMAND ;error code = BAD_COMMAND
- ret
-
-
- DoUpCall: ;input: RxFrameData contains a valid packet (CRC is OK)
- ; RxFrameLen contains its length
- push ds
- push es
- push si
- push di
-
- mov cx,count ;load packet length
- mov ax,receive_upcall ;is there a valid upcall address ?
- or ax,receive_upcall+2
- jz DoUpCall_ret ;jump if there is not
-
- mov ax,0 ;flag=0 - first upcall
- mov bx,0 ;handle = 0
- mov di,0 ;set es:di = NULL
- mov es,di
- call dword ptr [receive_upcall] ;first upcall
- mov ax,es ;check if application returned
- or ax,di ;valid buffer pointer
- jz DoUpCall_ret ;jump if not
-
- mov si,di ;make si=di before we alter di (for second upcall)
- mov bx,offset buf ;copy the packet to es:di
- mov cx,count ;packet length (exclude CRC)
- CopyLoop: mov al,[bx] ;loop over packet bytes
- inc bx ;would movsb do the job ?
- mov es:[di],al
- inc di
- loop CopyLoop
- mov cx,count ;again packet len for second call
- mov ax,es ;make ds=es (is not same as cs now !)
- mov ds,ax
- mov bx,0 ;handle 0
- mov ax,1 ;flag=1 - second upcall
-
- call dword ptr cs:[receive_upcall] ;second upcall
- ;we have to use cs: addressing in above call because we modified ds
-
- DoUpCall_ret:
- pop di
- pop si
- pop es
- pop ds
- ret
-
- buf:
- db 200h dup (?)
- over_buf:
-
- print_following_string: ;prints string following the call - modifies bx !
- ;string must following "call print_following_string"
- ;_must_ end with NULL character !
- pop bx ;pop return address from the stack
- push ax ;so we know where the char. string is
- push dx
- print_next_char:
- mov dl,cs:[bx] ;load next character
- inc bx
- and dl,dl ;NULL char ?
- jz string_end ;exit this loop if so
- mov ah,2 ;otherwise print it
- int 21h
- jmp short print_next_char
- string_end:
- pop dx
- pop ax
- push bx ;push new return address on stack
- ret
-
- SkipBlanks: ;mov to first non-SPACE nor TAB char.
- ;ds:[bx] = string address
- SkipThisChar:
- mov al,es:[bx] ;load next char.
- inc bx ;increment pointer
- cmp al,' ' ;space ?
- jz SkipThisChar ;jump if SPACE
- cmp al,9 ;TAB ?
- jz SkipThisChar ;jump if TAB
- dec bx ;if not SPACE nor TAB move pointer back
- ret ;ds:bx=address of non-blank character
- ;al=this character
-
- ReadOptions:
- push ax
- push bx
- push cx
- push dx
- mov bx,81h ;load offset to command line arguments
- NextOption:
- call SkipBlanks ;al=next non-blank char
- cmp al,13 ;carriage return ?
- clc
- jz ReadOptions_ret
- cmp al,'-' ;minus sign ?
- jz InterpreteOption ;if so go and interprete following chars
- ReadOptions_err:
- stc
- ReadOptions_ret:
- pop dx
- pop cx
- pop bx
- pop ax
- ret ;carry=1 => results are _not_ valid
-
- InterpreteOption: ;interprete an option
- ;ds:bx=address of '-' char.
- inc bx
- mov al,es:[bx] ;load char after '-'
- inc bx ;move pointer futher
- cmp al,'?'
- je OptionUsage
- cmp al,'i'
- je Opt_interrupt
-
- call UnknownOption ;if non of the above says the option
- ;was not recognized
- jmp ReadOptions_err
-
- Opt_interrupt:
- call ReadHexNumber
- mov packet_int_no,dl
- jmp short NextOption
-
- OptionUsage:
- call Print_following_string
- db 'Usage:',10,10,13
- db ' -? - this help text',10,13
- db ' -i<hex_int_no> - set interrupt vector',10,13
- db 10,0
- clc
- jmp NextOption
-
- UnknownOption: ;say the option not recognized
- push bx
- call Print_following_string
- db 'Unknown option: -',0
- mov dl,al
- mov ah,2
- int 21h
- call Print_following_string
- db 13,10,0
- pop bx
- ret
-
- ReadHexDigit: ;es:bx = digit pointer
- mov al,es:[bx]
- cmp al,'0'
- jc ReadHexDigit_ret ;jump if below '0'
- cmp al,'9'+1
- cmc
- jc ReadHexDigit_lett ;jump if above '9'
- sub al,'0'
- jmp short ReadHexDigit_ret
- ReadHexDigit_lett:
- cmp al,'a'
- jc ReadHexDigit_ret ;jump if below 'a'
- cmp al,'f'+1
- cmc
- jc ReadHexDigit_ret ;jump if above 'f'
- sub al,'a'-10
- ReadHexDigit_ret:
- ret ;carry=1 => not a hex digit, al=char.
- ;carry=0 => hex digit indeed, al=value
-
- ReadHexNumber:
- push cx
- mov cl,4
- mov dx,0
- ReadNextHexDigit:
- call ReadHexDigit
- jc ReadHexNumber_ret
- inc bx
- shl dx,cl ;multiply dx by 16
- or dl,al ;add the digit just read
- jmp short ReadNextHexDigit
- ReadHexNumber_ret:
- pop cx
- ret ;dx=the number,
- ;ds:bx *char where the interpretation stopped
- ;al=this character
-
- install_driver:
- call ReadOptions
- jnc DoPrintParam
- jmp BadUsage
- DoPrintParam:
- ; call PrintParameters
-
- ;--------------------------------
-
- push ds
- push cs
- pop ds
- mov ah,09h
- mov dx,offset txt1
- int 21h
- mov ax,35FDh
- int 21h
- mov si,bx
- mov ax,es:[si+4]
- cmp ax,4E35h
- jne no_tfpcx
- mov ah,0FEh
- int 0FDh
- cmp ax,0200h
- jne no_v2
- mov ah,09h
- mov dx,offset txt2
- int 21h
-
- pop es
- call ReadOptions
-
- xor ax,ax
- mov es,ax
- mov si,8*4+2
- mov ax,es:[si]
- mov ds,ax
- cli
- mov bx,46Abh
- mov byte ptr [bx],0EAh
- mov word ptr [bx+1],offset doupcallnow
- mov word ptr [bx+3],cs
- mov cx,ds:[0FC0h]
- mov ax,ds
- push cs
- pop ds
- mov bx,offset jump2
- mov [bx],ax
- mov data_s,cx
- sti
- mov ah,25h
- mov al,packet_int_no
- mov dx,offset DRVR_ISR
- int 21h
- mov dx,offset host
- mov ah,9
- int 21h
- call HostMode
- mov ah,31h
- mov dx,offset koniec
- shr dx,1
- int 21h
-
- no_v2:
- mov dx,offset txt3
- jmp no_
- no_tfpcx:
- mov dx,offset txt4
- no_:
- mov ah,09h
- int 21h
- n33: mov ax,4C01h
- int 21h
- BadUsage:
- call print_following_string
- db 'Bad options - type TFPCX2IP -? to get info',13,10,0
- jmp n33
-
- koniec:
- ends ax25_code
- end start
-